#region MIT License

/*
 *  Copyright (c) 2010 Nathan Palmer
 *  http://www.nathanpalmer.com/
 * 
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 * 
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 * 
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
 */

#endregion

using System;
using System.Collections.Generic;
using NLog;
using Quartz;
using Quartz.Impl;

namespace SimpleScheduler.Server.Listener
{
    public class JobLogger : IJobListener, ISchedulerListener
    {
        private Logger log;
        private IScheduler scheduler;
        private Dictionary<KeyValuePair<string, string>, Trigger> jobs;

        public JobLogger()
        {
            log = LogManager.GetLogger("JobLog");

            jobs = new Dictionary<KeyValuePair<string, string>, Trigger>();

            SchedulerRepository schedRep = SchedulerRepository.Instance;
            scheduler = schedRep.Lookup("QuartzServer");
        }

        private LogEventInfo PrepareMessage(JobExecutionContext context, string Message)
        {
            LogEventInfo logInfo = new LogEventInfo();
            logInfo.Context["job-group"] = context.JobDetail.Group;
            logInfo.Context["job-name"] = context.JobDetail.Name;
            logInfo.Level = LogLevel.Info;
            logInfo.TimeStamp = DateTime.Now;
            logInfo.Message = Message;

            return logInfo;
        }

        private LogEventInfo PrepareMessage(Trigger trigger, string Message)
        {
            LogEventInfo logInfo = new LogEventInfo();
            logInfo.Context["job-group"] = trigger.JobGroup;
            logInfo.Context["job-name"] = trigger.JobName;
            logInfo.Level = LogLevel.Info;
            logInfo.TimeStamp = DateTime.Now;
            logInfo.Message = Message;

            return logInfo;
        }

        public void JobToBeExecuted(JobExecutionContext context)
        {
            log.Log(PrepareMessage(context, string.Format("Job {0}.{1} is executing", context.JobDetail.Group, context.JobDetail.Name)));
        }

        public void JobExecutionVetoed(JobExecutionContext context)
        {
            log.Log(PrepareMessage(context, string.Format("Job {0}.{1} was vetoed", context.JobDetail.Group, context.JobDetail.Name)));
        }

        public void JobWasExecuted(JobExecutionContext context, JobExecutionException jobException)
        {
            log.Log(PrepareMessage(context, string.Format("Job {0}.{1} has executed", context.JobDetail.Group, context.JobDetail.Name)));
        }

        public string Name
        {
            get { return "Job Logger"; }
        }

        public void JobScheduled(Trigger trigger)
        {
            var jobKey = new KeyValuePair<string, string>(trigger.Name, trigger.Group);
            if (!jobs.ContainsKey(jobKey))
            {
                jobs.Add(jobKey, trigger);
            }

            log.Log(PrepareMessage(trigger, string.Format("Job {0}.{1} has been scheduled for {2}", trigger.Group, trigger.JobName, trigger.ToString())));
        }

        public void JobUnscheduled(string triggerName, string triggerGroup)
        {
            var jobKey = new KeyValuePair<string, string>(triggerName, triggerGroup);
            Trigger trigger = jobs[jobKey];
            jobs.Remove(jobKey);

            log.Log(PrepareMessage(trigger, string.Format("Job {0}.{1} has been removed", trigger.Group, trigger.JobName, trigger.ToString())));
        }

        public void TriggerFinalized(Trigger trigger)
        {
            
        }

        public void TriggersPaused(string triggerName, string triggerGroup)
        {
            
        }

        public void TriggersResumed(string triggerName, string triggerGroup)
        {
            
        }

        public void JobAdded(JobDetail jobDetail)
        {
            
        }

        public void JobDeleted(string jobName, string groupName)
        {
            
        }

        public void JobsPaused(string jobName, string jobGroup)
        {
            
        }

        public void JobsResumed(string jobName, string jobGroup)
        {
            
        }

        public void SchedulerError(string msg, SchedulerException cause)
        {
            
        }

        public void SchedulerInStandbyMode()
        {
            
        }

        public void SchedulerStarted()
        {
            
        }

        public void SchedulerShutdown()
        {
            
        }

        public void SchedulerShuttingdown()
        {
            
        }
    }
}